import {
  IAuthzIoService,
  IUndoRedoService,
  LocaleType,
  LogLevel,
  Univer,
} from '@univerjs/core';
import { UniverFormulaEnginePlugin } from '@univerjs/engine-formula';
import { UniverThreadCommentPlugin } from '@univerjs/thread-comment';
import { UniverDrawingPlugin } from '@univerjs/drawing';
import { UniverDocsPlugin } from '@univerjs/docs';
import { UniverDocsDrawingPlugin } from '@univerjs/docs-drawing';
import { UniverSheetsPlugin } from '@univerjs/sheets';
import { UniverSheetsFormulaPlugin } from '@univerjs/sheets-formula';
import { UniverDataValidationPlugin } from '@univerjs/data-validation';
import { UniverSheetsDataValidationPlugin } from '@univerjs/sheets-data-validation';
import { UniverSheetsFilterPlugin } from '@univerjs/sheets-filter';
import { UniverSheetsHyperLinkPlugin } from '@univerjs/sheets-hyper-link';
import { UniverSheetsDrawingPlugin } from '@univerjs/sheets-drawing';
import { UniverSheetsSortPlugin } from '@univerjs/sheets-sort';
import { UniverSheetsConditionalFormattingPlugin } from '@univerjs/sheets-conditional-formatting';
import { UniverCollaborationPlugin } from '@univerjs-pro/collaboration';
import { UniverCollaborationClientPlugin } from '@univerjs-pro/collaboration-client';
import {
  NodeCollaborationSocketService,
  UniverCollaborationClientNodePlugin,
} from '@univerjs-pro/collaboration-client-node';
import { UniverSheetsChartPlugin } from '@univerjs-pro/sheets-chart';
import { UniverLicensePlugin } from '@univerjs-pro/license';
import { MyBizPlugin } from './biz/plugin/plugin.js';

// #region Facade

import '@univerjs/core/facade';
import '@univerjs/sheets/facade';
import '@univerjs-pro/collaboration-client/facade';
import { FUniver } from '@univerjs/core/facade';

// #endregion

export function createUniver(): {
  univer: Univer;
  univerAPI: FUniver;
} {
  const univer = new Univer({
    locale: LocaleType.EN_US,
    locales: {
      [LocaleType.EN_US]: {},
    },
    logLevel: LogLevel.INFO,
    override: [
      [IUndoRedoService, null],
      [IAuthzIoService, null],
    ],
  });

  // 注册插件
  registerBasicPlugins(univer);
  registerSheetPlugins(univer);
  registerCollaborationPlugins(univer);

  // 注册我们自己的业务插件
  registerBizPlugin(univer);

  const univerAPI = FUniver.newAPI(univer);
  return { univer, univerAPI };
}

function registerBasicPlugins(univer: Univer): void {
  univer.registerPlugin(UniverFormulaEnginePlugin);
  univer.registerPlugin(UniverThreadCommentPlugin);
  univer.registerPlugin(UniverDrawingPlugin);
  univer.registerPlugin(UniverLicensePlugin);
}

function registerSheetPlugins(univer: Univer): void {
  univer.registerPlugin(UniverDocsPlugin);
  univer.registerPlugin(UniverDocsDrawingPlugin);
  univer.registerPlugin(UniverSheetsPlugin);
  univer.registerPlugin(UniverSheetsFormulaPlugin);
  univer.registerPlugin(UniverDataValidationPlugin);
  univer.registerPlugin(UniverSheetsDataValidationPlugin);
  univer.registerPlugin(UniverSheetsFilterPlugin);
  univer.registerPlugin(UniverSheetsHyperLinkPlugin);
  univer.registerPlugin(UniverSheetsDrawingPlugin);
  univer.registerPlugin(UniverSheetsSortPlugin);
  univer.registerPlugin(UniverSheetsConditionalFormattingPlugin);
  univer.registerPlugin(UniverSheetsChartPlugin);
}

function registerCollaborationPlugins(univer: Univer): void {
  // 注册协作相关的插件，部分插件是和桌面端共用的
  univer.registerPlugin(UniverCollaborationPlugin);
  univer.registerPlugin(UniverCollaborationClientPlugin, {
    socketService: NodeCollaborationSocketService,
    enableOfflineEditing: false,
    enableSingleActiveInstanceLock: false,
    snapshotServerUrl: 'http://localhost:8000/universer-api/snapshot',
    collabSubmitChangesetUrl: 'http://localhost:8000/universer-api/comb',
    collabWebSocketUrl: 'ws://localhost:8000/universer-api/comb/connect',
    wsSessionTicketUrl:
      'http://localhost:8000/universer-api/user/session-ticket',
    sendChangesetTimeout: 200,
    retryConnectingInterval: 1000,
  });

  // 注意我们这里通过注册 UniverCollaborationClientNodePlugin 来打开
  // 环境下的协作功能
  univer.registerPlugin(UniverCollaborationClientNodePlugin);
}

function registerBizPlugin(univer: Univer): void {
  // 注册我们自己的业务插件，实现自定义业务逻辑
  univer.registerPlugin(MyBizPlugin);
}
